##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx copy project dependent dlls to binary dir, windows
function(my_cp_dlls target)
    if(NOT WIN32)
        message(STATUS "[my] Skip, not in windows")
        return()
    endif()
    add_custom_command(TARGET ${target} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${target}> $<TARGET_FILE_DIR:${target}>
        COMMAND_EXPAND_LISTS
        COMMENT "Copying DLLs to build directory")
endfunction()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 定义一个函数来打印所有相关定义
function(my_prt_target_definitions target)
    if(NOT TARGET ${target})
        message(WARNING "目标 ${target} 不存在")
        return()
    endif()

    # 获取不同作用域的属性
    get_target_property(private_defs ${target} COMPILE_DEFINITIONS)
    get_target_property(public_defs ${target} INTERFACE_COMPILE_DEFINITIONS)
    get_target_property(imported_defs ${target} IMPORTED_CONFIGURATIONS) # 对于导入的目标

    message("目标 ${target} 的宏定义:")

    if(private_defs)
        message("  PRIVATE: ${private_defs}")
    endif()

    if(public_defs)
        message("  PUBLIC/INTERFACE: ${public_defs}")
    endif()

    # 处理生成器表达式（可能需要进一步处理）
    get_target_property(genex_defs ${target} COMPILE_DEFINITIONS$<$<CONFIG:DEBUG>:DEBUG>)
    if(genex_defs)
        message("  生成器表达式相关: ${genex_defs}")
    endif()
endfunction()

##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 配置 MSVC 的 RelWithDebInfo 模式
function(my_config_msvc_relwithdebinfo target_name)
    if(NOT TARGET ${target_name})
        message(WARNING "Target ${target_name} 不存在")
        return()
    endif()

    # 确保只在 MSVC 编译器下执行
    set(MY_REL_DEB_OPTS "/utf-8;/EHsc;/Zc:__cplusplus;/permissive-;/Od;/Zi;/DDEBUG;/UNDEBUG")
    list(JOIN MY_REL_DEB_OPTS_CUDA "," MY_REL_DEB_OPTS)
    # 针对 RelWithDebInfo 关闭优化，启用调试宏
    target_compile_options(${target_name} PRIVATE
        # c++ 选项: 禁用优化; 确保生成调试信息; 定义 DEBUG 宏; 取消 NDEBUG 宏
        "$<$<AND:$<CONFIG:RelWithDebInfo>,$<COMPILE_LANGUAGE:CXX>>:${MY_REL_DEB_OPTS}>" # C++: 合并所有选项
        "$<$<AND:$<CONFIG:RelWithDebInfo>,$<COMPILE_LANGUAGE:CUDA>>:-Xcompiler=${MY_REL_DEB_OPTS_CUDA}>" # CUDA: 合并所有选项
    )

    # 确保生成 PDB 文件
    target_link_options(${target_name} PRIVATE
        "$<$<CONFIG:RelWithDebInfo>:/DEBUG>" # 确保生成 PDB 文件
    )

    # 设置运行时库为 Debug 版本（可选，但可能影响 ABI）
    # 如需启用，取消下面的注释
    # set_property(TARGET ${target_name} PROPERTY
    #     MSVC_RUNTIME_LIBRARY "MultiThreadedDebug$<$<CONFIG:Debug>:Debug>"
    # )
endfunction()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 生成和配置, export header; 导出符号的头文件
include(GenerateExportHeader)
function(my_config_export_header target_name export_dir)
    # 参数检查
    if(NOT TARGET ${target_name})
        message(WARNING "Target ${target_name} not exist")
        return()
    endif()

    # 确保导出目录存在
    file(MAKE_DIRECTORY ${export_dir})

    # 确保导出目录已设置
    if(NOT export_dir)
        set(export_dir "${CMAKE_BINARY_DIR}/export_headers")
        message(STATUS "Non-exist export directory, use default: ${export_dir}")
    endif()

    # 设置导出头文件路径; PARENT_SCOPE 为了方便调用者使用 header 的路径
    set(${target_name}_EXPORTS "${export_dir}/${target_name}_export.h" PARENT_SCOPE)

    # 生成导出头文件
    generate_export_header(${target_name} EXPORT_FILE_NAME "${export_dir}/${target_name}_export.h")

    # 设置目标的包含目录
    target_include_directories(${target_name} PUBLIC
        $<BUILD_INTERFACE:${export_dir}>
        $<INSTALL_INTERFACE:include>
    )

    # 安装导出头文件
    install(FILES "${export_dir}/${target_name}_export.h" DESTINATION include)

endfunction()